package cn.xuchunh.campusbbs.widget;

import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;

import com.facebook.rebound.Spring;
import com.facebook.rebound.SpringConfig;
import com.facebook.rebound.SpringConfigRegistry;
import com.facebook.rebound.SpringListener;
import com.facebook.rebound.SpringSystem;
import com.facebook.rebound.SpringUtil;

import java.util.Iterator;

import cn.xuchunh.campusbbs.utils.DeviceUtil;

/**
 * Created by XuChunH on 2015/10/6.
 */
public class ReboundLayout extends ViewGroup implements SpringListener {

    private Spring translationSpring;
    private int childWidth;
    private int childX;
    private boolean isPlaying = false;

    private float tension;
    private float friction;

    public ReboundLayout(Context context) {
        super(context);
        init();
    }

    public ReboundLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public ReboundLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public ReboundLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init();
    }

    private void init() {
        translationSpring = SpringSystem.create().createSpring();
        translationSpring.addListener(this);
        SpringConfigRegistry springConfigRegistry = SpringConfigRegistry.getInstance();
        Iterator<SpringConfig> iterator = springConfigRegistry.getAllSpringConfig().keySet().iterator();
        if(iterator.hasNext()){
            SpringConfig springConfig = iterator.next();
            tension = (float) springConfig.tension;
            friction = (float) springConfig.friction;
        }
    }

    public void dimiss(SpringListener listener) {
        translationSpring.addListener(listener);
        translationSpring.setEndValue(0);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        View child = getChildAt(0);
        if (child != null) {
            child.layout(l, t, Math.min(child.getMeasuredWidth() + l, r), Math.min(child.getMeasuredHeight() + t, b));
            childWidth = child.getMeasuredWidth();
            childX = l + getPaddingLeft() + ((MarginLayoutParams) child.getLayoutParams()).leftMargin;
            if (!isPlaying) {
                translationSpring.setEndValue(1);
                isPlaying = true;
            }

        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        View child = getChildAt(0);
        if (child != null) {
            measureChild(child, widthMeasureSpec, heightMeasureSpec);
        }
        setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected LayoutParams generateDefaultLayoutParams() {
        return new MarginLayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
    }

    @Override
    protected LayoutParams generateLayoutParams(LayoutParams p) {
        return super.generateLayoutParams(p);
    }

    @Override
    protected boolean addViewInLayout(View child, int index, ViewGroup.LayoutParams params) {
        if (getChildCount() > 1) {
            return false;
        }
        return super.addViewInLayout(child, index, params);
    }

    @Override
    public void addView(View child) {
        if (getChildCount() > 1) {
            return;
        }
        super.addView(child);
    }

    @Override
    public void onSpringUpdate(Spring spring) {
        float delta = (float) SpringUtil.mapValueFromRangeToRange(spring.getCurrentValue(), 0, 1, childWidth, 0);
        getChildAt(0).setTranslationX(childX + delta);
    }

    @Override
    public void onSpringAtRest(Spring spring) {
        isPlaying = false;
    }

    @Override
    public void onSpringActivate(Spring spring) {

    }

    @Override
    public void onSpringEndStateChange(Spring spring) {

    }

    public float getFriction() {
        return friction;
    }

    public void setFriction(int friction) {
        this.friction = friction;
    }

    public float getTension() {
        return tension;
    }

    public void setTension(int tension) {
        this.tension = tension;
    }
}
